from django.template import RequestContext
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.contrib.auth import authenticate,logout,login
from django.contrib.auth.models import User
from django.core.paginator import Paginator
import ImageFile, sys

from online_shop.employees.forms import EmployeeLoginForm, UserForm, EmployeeAccountForm, EmployeePasswordForm
from online_shop.products.models import categories, sub_categories, products, inventory_records
from online_shop.products.forms import ProductForm, InventoryManagementForm, CategoryForm, SubcategoryForm
from online_shop.orders.models import orders, order_status, order_details
from online_shop.orders.forms import OrderStatusForm
from online_shop.utils import generate_page_bar

# Create your views here.

# employee admin page
# url: /employee
def employee_main_page(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_staff and user.is_active:
        variables = RequestContext(request,{
            'user': user,
        })
        return render_to_response(
            'employee/employee_base.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')
# employee login
# url: /employee/login
def employee_login(request):
    message = ''
    if request.method == 'POST':
        # get login info from Login form
        form = EmployeeLoginForm(request.POST)
        if form.is_valid():
            user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
            if user is not None:
                if user.is_active and user.is_staff:
                    login(request, user)
                    return HttpResponseRedirect('/employee/')
                else:
                    message = "Your account has no permission to access."
            else:    
                message = "Your username and password were incorrect."
        else:
            message = "Username and password are required!"
    variables = RequestContext(request,{
        'message':message,
    })
    return render_to_response(
        'employee/employee_login.html',
        variables,
    )
# employee logout
# url: /employee/logout
def employee_logout(request):
    logout(request)
    return HttpResponseRedirect('/employee/login')

# employee self account
# url: /employee/account
def employee_account(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_staff and user.is_active:
        message = ''
        error = ''
        
        if request.method == 'POST':
            form = EmployeeAccountForm(request.POST)
            if form.is_valid():
                try:
                    user.first_name = form.cleaned_data['first_name']
                    user.last_name = form.cleaned_data['last_name']
                    user.email = form.cleaned_data['email']
                    user.save()
                    message = 'Saving successfully'
                except:
                    error = 'Failed to save the infomation.'
            else:
                error = form.errors
        else:
            form = EmployeeAccountForm(initial={'first_name':user.first_name,'last_name':user.last_name,'email':user.email})
        variables = RequestContext(request,{
            'user': user,
            'form': form,
            'message': message,
            'error': error,
        })
        return render_to_response(
            'employee/account.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')
    
# employee password change
# url: /employee/account/password
def employee_account_password(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_staff and user.is_active:
        message = ''
        error = ''
        
        if request.method == 'POST':
            form = EmployeePasswordForm(request.POST)
            if form.is_valid():
                old_password = form.cleaned_data['old_password']
                if user.check_password(old_password):                    
                    user.set_password(form.cleaned_data['new_password'])
                    user.save()
                    return HttpResponseRedirect('/employee/account/')                    
                else:
                    error = 'Old password dose not match!'                    
            else:
                error = form.errors
        else:
            form = EmployeePasswordForm()
            
        variables = RequestContext(request,{
            'user': user,
            'form': form,
            'message': message,
            'error': error,
        })
        return render_to_response(
            'employee/account_password.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')

# admin products list
# url: /employee/products/
def employee_admin_products_list(request):    
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        items_per_page = 30
        current_page = 1
        if "page" in request.GET:
            current_page = int(request.GET['page'])
            if current_page<1:
                current_page = 1
        results = products.objects.select_related()
        p = Paginator(results, items_per_page)
        if current_page > p.num_pages:
            current_page = p.num_pages
        page = p.page(current_page)
        page.current_page = current_page
        page.url = "/employee/products/?page="
        page.bar = generate_page_bar(p,current_page)

        productslist = p.page(current_page).object_list;
        
        variables = RequestContext(request,{
            'user': user,
            'cateogries': categories.objects.all(),
            'products': productslist,
            'page': page,
        })
        return render_to_response(
            'employee/product_list.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')

# add new product
# url: employee/products/add/
def employee_admin_product_add(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ''
        if request.method == 'POST':
            form = ProductForm(request.POST,request.FILES)
            if form.is_valid():
                try:
                    form.save()
                    
                    return HttpResponseRedirect('/employee/products')
                except:
                    message = sys.exc_info()
            else:
                message = form.errors
        else:
            form = ProductForm() 
        variables = RequestContext(request,{
            'user': user,
            'operation': 'Add',
            'form': form,
            'message': message,
        })
        return render_to_response(
            'employee/product.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')

# edit product
# url: employee/products/edit/<product_id>/
def employee_admin_product_edit(request,product_id,message=''):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        
        #check if product_id is existed
        try:
            product = products.objects.get(id=product_id)       
            # Edit operation
            if request.method == 'POST':
                form = ProductForm(request.POST,request.FILES,instance=product)
                if form.is_valid():
                    try:
                        # If edit include image change
                        #if request.FILES:
                        #    message = 'has image'
                        #    form.image
                        #p_form = ProductForm(product)
                        #p_form.changed_data(request.POST)
                        form.save()
                        #product.subcategory = form.cleaned_data['subcategory']
                        #product.name = form.cleaned_data['name']
                        #product.price = form.cleaned_data['price']
                        #product.description = form.cleaned_data['description']
                        #product.status = form.cleaned_data['status']
                        #product.recommended = form.cleaned_data['recommended']
                        #product.save()
                        return HttpResponseRedirect('/employee/products')
                    except:
                        message = 'Faild to edit product.'
                else:
                    message = form.errors
            else:
                #show orginal info
                data = {
                    #'name':product.name,
                    #'price':product.price,
                    #'description': product.description,
                    #'image': product.image,
                    #'subcategory': product.subcategory.id,
                    'category': product.subcategory.category.id,
                    #'status':product.status,
                    #'recommended':product.recommended,
                }
                form = ProductForm(initial={'category': product.subcategory.category.id},instance=product)
                
            variables = RequestContext(request,{
                'user': user,
                'operation': 'Edit',
                'form': form,
                'message': message,
                'product': product,
            })
            return render_to_response(
                'employee/product.html',
                variables,
            )
        except:
            # if no such product, go back to product list page
            return HttpResponseRedirect('/employee/products')
    else:
        return HttpResponseRedirect('/employee/login')

# delete product
# url: employee/products/edit/(?P<product_id>\d+)/delete/
def employee_admin_product_delete(request,product_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        #check if product_id is existed
        try:
            product = products.objects.get(id=product_id)
            product.delete()
            return HttpResponseRedirect('/employee/products')
        except:
            #message = 'Failed to delete the product.'
            #message = sys.exc_info()
            return HttpResponseRedirect('/employee/products/edit/'+product_id)
            #return employee_admin_product_edit(request,product_id,message)
    else:
        return HttpResponseRedirect('/employee/login')

# Inventroy manage
#  * add product amount
#  * change product amount
# url: employee/products/inventory/(?P<product_id>\d+)/
def inventory_manage(request, product_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        #check if product_id is existed
        product = get_object_or_404(products,id=product_id)
        message = ''
        try:
            # if is the first time to load inventory create it
            inventory = inventory_records.objects.get(product=product)
        except:
            inventory = inventory_records.objects.create(product=product)
        try:
            # if the request action is from form submit
            
            if request.method == 'POST':
                form = InventoryManagementForm(request.POST)
                if form.is_valid():
                    amount = form.cleaned_data['amount']
                    changeType = form.cleaned_data['changeType']
                    if changeType=='add':
                        inventory.total = inventory.total+amount
                        inventory.available = inventory.available+amount
                    elif changeType=='change':
                        lock_num = inventory.total - inventory.available
                        new_available = amount - lock_num
                        if new_available>0:
                            inventory.available = new_available
                        else:
                            inventory.available = 0
                        inventory.total = amount
                        
                    inventory.save()
                    message = "Successed to change the inventory amount."
                else:
                    message = form.errors
            #reload the product info
            product = get_object_or_404(products,id=product_id)
        except EOFError:
            message = 'Failed to change the inventory data.'
        
        variables = RequestContext(request,{
            'user': user,
            'product': product,
            'message': message,
        })
        return render_to_response(
            'employee/inventory.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')

# Category manage
# url: employee/products/category/
def category_manage(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        category_list = categories.objects.all()
        
        
        
        variables = RequestContext(request,{
            'user': user,
            'categories': category_list,
        })
        return render_to_response(
            'employee/category_list.html',
            variables,
        )        
    else:
        return HttpResponseRedirect('/employee/login')

# Category add
# url: employee/products/category/add
def category_add(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ''
        # if the action is from POST
        if request.method == 'POST':
            form = CategoryForm(request.POST)
            if form.is_valid():
                form.save();
                return HttpResponseRedirect('/employee/products/category/')
            else:
                message = form.errors
        else:
            form = CategoryForm(initial={"weight":0})
        
        variables = RequestContext(request,{
            'user': user,
            'operation': 'Add',
            'form': form,
            'message': message,
        })
        return render_to_response(
            'employee/category.html',
            variables,
        )        
    else:
        return HttpResponseRedirect('/employee/login')
        
# Categroy Edit
# url: employee/products/category/edit/<category_id>
def category_edit(request, category_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ''
        category = get_object_or_404(categories,id=category_id)
        # if the action is from POST
        if request.method == 'POST':
            form = CategoryForm(request.POST, instance=category)
            if form.is_valid():
                form.save();
                return HttpResponseRedirect('/employee/products/category/')
            else:
                message = form.errors
        else:
            form = CategoryForm(instance=category)
        
        variables = RequestContext(request,{
            'user': user,
            'operation': 'Edit',
            'form': form,
            'message': message,
        })
        return render_to_response(
            'employee/category.html',
            variables,
        )        
    else:
        return HttpResponseRedirect('/employee/login')

# Delete category
# url: employee/products/category/delete/<category_id>
def category_delete(request, category_id):
     # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        category = get_object_or_404(categories,id=category_id)
        try:
            category.delete()
        except:
            pass
        return HttpResponseRedirect('/employee/products/category/')
    else:
        return HttpResponseRedirect('/employee/login')
        
# Subcategory add
# url: employee/products/subcategory/add
def subcategory_add(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ''
        # if the action is from POST
        if request.method == 'POST':
            form = SubcategoryForm(request.POST)
            if form.is_valid():
                form.save();
                return HttpResponseRedirect('/employee/products/category/')
            else:
                message = form.errors
        else:
            form = SubcategoryForm(initial={"weight":0})
        
        variables = RequestContext(request,{
            'user': user,
            'operation': 'Add',
            'form': form,
            'message': message,
        })
        return render_to_response(
            'employee/subcategory.html',
            variables,
        )        
    else:
        return HttpResponseRedirect('/employee/login')
        
# Subcategroy Edit
# url: employee/products/subcategory/edit/<subcategory_id>
def subcategory_edit(request, subcategory_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ''
        subcategory = get_object_or_404(sub_categories,id=subcategory_id)
        # if the action is from POST
        if request.method == 'POST':
            form = SubcategoryForm(request.POST, instance=subcategory)
            if form.is_valid():
                form.save();
                return HttpResponseRedirect('/employee/products/category/')
            else:
                message = form.errors
        else:
            form = SubcategoryForm(instance=subcategory)
        
        variables = RequestContext(request,{
            'user': user,
            'operation': 'Edit',
            'form': form,
            'message': message,
        })
        return render_to_response(
            'employee/subcategory.html',
            variables,
        )        
    else:
        return HttpResponseRedirect('/employee/login')

# Delete subcategory
# url: employee/products/subcategory/delete/<subcategory_id>
def subcategory_delete(request, subcategory_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        subcategory = get_object_or_404(sub_categories,id=subcategory_id)
        try:
            subcategory.delete()
        except:
            pass
        return HttpResponseRedirect('/employee/products/category/')
    else:
        return HttpResponseRedirect('/employee/login')
        
#orders management
# url: employee/orders
def employee_admin_orders_list(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        items_per_page = 30
        current_page = 1
        if "page" in request.GET:
            current_page = int(request.GET['page'])
            if current_page<1:
                current_page = 1
        #get orders
        results = orders.objects.all()
        p = Paginator(results, items_per_page)
        if current_page > p.num_pages:
            current_page = p.num_pages
        page = p.page(current_page)
        page.current_page = current_page
        page.url = "/employee/orders/?page="
        page.bar = generate_page_bar(p,current_page)
        
        #orderlist = p.page(current_page).object_list;
        variables = RequestContext(request,{
            'user': user,
            #'orders': orderlist,
            'page':page,
        })
        return render_to_response(
            'employee/order_list.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')
# manage the state of order
# url: /employee/orders/manage/order_id
def employee_admin_order_manage(request,order_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ""
        error = ""
        #get order
        order = get_object_or_404(orders, id=order_id)
        # if request from form submit
        if request.method == "POST":
            
            status = request.POST['order_opperation']
            if status == 'SHIPPED' and order.status.type == 'PROCESSED':
                #check order status, it chould only be a processed order
                order.status = order_status.objects.get(type=status)
                order.save()
                #change the inverntory
                detail_results = order_details.objects.select_related().filter(idorder=order)
                for detail in detail_results:
                    inventory = inventory_records.objects.get(product=detail.idproduct)
                    inventory.total = inventory.total - detail.count
                    inventory.sales_history =  inventory.sales_history + detail.count
                    inventory.save()
                message = "Change order status successfully"
            elif status == 'CANCELED':
                if order.status.type == 'UNPAID' or order.status.type == 'PROCESSED':
                    order.status = order_status.objects.get(type=status)
                    order.save()
                    #release the locked goods in inventory
                    detail_results = order_details.objects.select_related().filter(idorder=order)
                    for detail in detail_results:
                        inventory = inventory_records.objects.get(product=detail.idproduct)
                        inventory.available = inventory.available + detail.count
                        inventory.save()
                    message = "Change order status successfully"
                else:
                    error = "The goods have already be sended, you can not change the status now."
                
            #form = OrderStatusForm(request.POST)
            #if form.is_valid():
                #status = order_status
                #order.status = order_status.objects.get(id=form.cleaned_data['status'])               
                #order.save()
                #message = "Change order status successfully"
            #else:
                #error = form.errors
        #else:
            #form = OrderStatusForm(initial={"status":order.status})
        variables = RequestContext(request,{
            'user': user,
            'order': order,
            #'form': form,
            'message': message,
            'error': error,
        })
        return render_to_response(
            'employee/order.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')
  
# show users list
# url: employee/users/
def employee_admin_users_list(request):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        items_per_page = 30
        current_page = 1
        if "page" in request.GET:
            current_page = int(request.GET['page'])
            if current_page<1:
                current_page = 1
        #get users' list
        results = User.objects.all()
        p = Paginator(results, items_per_page)
        if current_page > p.num_pages:
            current_page = p.num_pages
        page = p.page(current_page)
        userlist = page.object_list;
        page.current_page = current_page
        page.url = "/employee/users/?page="
        page.bar = generate_page_bar(p,current_page)
        variables = RequestContext(request,{
            'user': user,
            'users': userlist,
            'page': page
        })
        return render_to_response(
            'employee/user_list.html',
            variables,
        )
    else:
        return HttpResponseRedirect('/employee/login')

# manange user
# url: employee/users/manage/<user_id>/
def employee_admin_user_manage(request,user_id):
    # check if the current user has the permission to employee page
    try:
        # check if user is login
        user = User.objects.get(username=request.user.username)
    except User.DoesNotExist:
        return HttpResponseRedirect('/employee/login')
    #check if the user has the permission to access the admin site    
    if user.is_active and user.is_staff:
        message = ''
        error = ''
        #get user
        t_user = get_object_or_404(User, id=user_id)
        # if request from post
        if request.method == 'POST':
            form = UserForm(request.POST)
            if form.is_valid():
                t_user.is_active = form.cleaned_data['active']
                t_user.save()
                message = 'Successed to save the infomation.'
            else:
                error = form.errors
        
        form = UserForm(initial={'active':t_user.is_active})
        variables = RequestContext(request,{
            'user': user,
            't_user': t_user,
            'form': form,
            'message': message,
            'error': error,
        })
        return render_to_response(
            'employee/user.html',
            variables,
        )
        
    else:
        return HttpResponseRedirect('/employee/login')

